﻿using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using Eflong.Utility;

namespace Eflong
{
    public static class EflongProgram
    {
        public static string AppName;

        public static void MainRun( string appName , EflongTryIco mainForm )
        {
            AppName = appName;

            Process process = EflongProgram.GetRunningInstance( );
            if ( process != null )
            {
                Thread.Sleep( 1000 );
                process = EflongProgram.GetRunningInstance( );
            }
            if ( process != null )
            {
                EflongProgram.HandleRunningInstance( process );
            }
            else
            {
                LogWrapper.Logger.Info( "" );
                LogWrapper.Logger.Info( "*********************************************" );
                LogWrapper.Logger.Info( "" );
                LogWrapper.Logger.Info( AppName + " 启动" );
                LogWrapper.Logger.Info( "" );
                LogWrapper.Logger.Info( "*********************************************" );
                LogWrapper.Logger.Info( "" );

                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( EflongProgram.CurrentDomain_UnhandledException );
                Application.ThreadException += new ThreadExceptionEventHandler( EflongProgram.Application_ThreadException );

                Application.Run( mainForm );

                bool IsRestart = mainForm.IsRestart;
                if ( IsRestart )
                {
                    LogWrapper.Logger.Info( "" );
                    LogWrapper.Logger.Info( "*********************************************" );
                    LogWrapper.Logger.Info( "" );
                    LogWrapper.Logger.Info( AppName + " 准备重启" );
                    LogWrapper.Logger.Info( "" );
                    LogWrapper.Logger.Info( "*********************************************" );
                    Process currentProcess = System.Diagnostics.Process.GetCurrentProcess( );
                    EflongProgram.RestartApp( currentProcess.Id , currentProcess.MainModule.FileName );
                }
                else
                {
                    LogWrapper.Logger.Info( "" );
                    LogWrapper.Logger.Info( "*********************************************" );
                    LogWrapper.Logger.Info( "" );
                    LogWrapper.Logger.Info( AppName + " 退出" );
                    LogWrapper.Logger.Info( "" );
                    LogWrapper.Logger.Info( "*********************************************" );

                    LogWrapper.Logger.Info( "" );
                }
            }
        }

        public static void CurrentDomain_UnhandledException( object sender , UnhandledExceptionEventArgs e )
        {
            LogWrapper.Logger.Error( "In CurrentDomain_UnhandledException" );
            Exception ex = ( Exception )e.ExceptionObject;
            LogWrapper.Logger.Error( sender , ex );
        }

        public static void Application_ThreadException( object sender , ThreadExceptionEventArgs e )
        {
            LogWrapper.Logger.Error( "in Application_ThreadException" );
            LogWrapper.Logger.Error( sender , e.Exception );
        }

        /// <summary>
        /// 重启应用
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="applicationName"></param>
        public static void RestartApp( int pid , string applicationName )
        {
            // Wait for the process to terminate
            Process process = null;
            try
            {
                //Debug.WriteLine("process.WaitForExit ...");
                process = Process.GetProcessById( pid );

                process.WaitForExit( 5000 );

                LogWrapper.Logger.Info( "process.WaitForExit ... end" );

                if ( !process.HasExited )
                {
                    try
                    {
                        LogWrapper.Logger.Info( "Restart:" + applicationName );
                        Process.Start( applicationName , "Restart" );
                    }
                    finally
                    {
                        LogWrapper.Logger.Info( "process.Kill()" );
                        process.Kill( );
                    }
                }
                else
                {
                    LogWrapper.Logger.Info( "Restart:" + applicationName );
                    Process.Start( applicationName , "Restart" );
                }
            }
            catch ( ArgumentException ex )
            {
                // ArgumentException to indicate that the
                // process doesn't exist?   LAME!!
                Debug.WriteLine( "process.WaitForExit err -> " + ex.Message );
            }
            try
            {
                // Process.Start(applicationName, "Restart");
            }
            finally
            {
                Debug.WriteLine( "Process.Start ... " + applicationName );
            }
        }

        /// <summary>
        /// 获取应用程序句柄，设置应用程序前台运行，并返回bool值
        /// </summary>
        public static bool HandleRunningInstance( System.Diagnostics.Process instance )
        {
            IntPtr intPtr = new IntPtr( instance.MainWindowHandle.ToInt32( ) == 0 ?
           WinAPI.FindWindow( null , AppName ) : instance.MainWindowHandle.ToInt32( ) );

            if ( intPtr != IntPtr.Zero )
            {
                //使窗口最大化
                WinAPI.ShowWindowAsync( intPtr , WinAPI.WS_SHOWMAX );

                //WinAPI.ShowWindowAsync(intPtr, WinAPI.WS_SHOWNORMAL);
                //设置前台进程为已运行的进程,而现有进程继续执行至进程结束(在这里跑完MAIN函数就结束掉了)
                return WinAPI.SetForegroundWindow( intPtr );
            }
            else
            {
                MessageBoxButtons buttons = MessageBoxButtons.OK;
                MessageBoxIcon icon = MessageBoxIcon.Stop;
                DialogResult result = MessageBox.Show( "您已经启动一个 " + AppName + " 了，本程序将退出" , AppName + " 提示 " , buttons , icon );
                return false;
            }
        }

        public static System.Diagnostics.Process GetRunningInstance( )
        {
            //获取当前进程
            System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess( );

            //获取当前运行程序完全限定名

            string currentFileName = currentProcess.MainModule.FileName;
            Console.WriteLine( currentFileName );

            //获取进程名为ProcessName的Process数组。

            System.Diagnostics.Process[ ] processes = System.Diagnostics.Process.GetProcessesByName( currentProcess.ProcessName );

            //遍历有相同进程名称正在运行的进程
            foreach ( System.Diagnostics.Process process in processes )
            {
                if ( process.MainModule.FileName == currentFileName || process.ProcessName == "KWBridge" )
                {
                    if ( process.Id != currentProcess.Id )//根据进程ID排除当前进程
                        return process;//返回已运行的进程实例
                }
            }
            return null;
        }

        /*
         *
         System.Int32 processid;
Process process;

//Retrieve the additional information about a specific process
processid = Int32.Parse(txtProcessID.Text);
process = System.Diagnostics.Process.GetProcessById(processid);
s = s + "该进程的总体优先级类别:" + Convert.ToString(process.PriorityClass) + " \r\n";
s = s + "由该进程打开的句柄数:" + process.HandleCount + "\r\n";
s = s + "该进程的主窗口标题:" + process.MainWindowTitle + "\r\n";
s = s + " 该进程允许的最小工作集大小:" + process.MinWorkingSet.ToString() + " \r\n";
s = s + "该进程允许的最大工作集大小:" + process.MaxWorkingSet.ToString() + " \r\n";
s = s + "该进程的分页内存大小:" + process.PagedMemorySize + "\r\n";
s = s + "该进程的峰值分页内存大小:" + process.PeakPagedMemorySize + "\r\n";
         *
         */
    }
}